<template>
  <!-- 使用外层DOM来统一坐标系-->
  <div class="controllerContainer" @mousemove="mouseMove">
    <div class="bg"></div>
    <div
      id="controllerBall"
      ref="ballDom"
      @mousedown="mouseDown"
      @mouseup="mouseUp"
      :style="{ top: top + 'px', left: left + 'px' }"
    ></div>
  </div>
</template>

<script>
import { onMounted, ref, reactive, toRefs, computed } from "vue";
import $ from "jquery"; //原生offset有bug,用jq是offset()

export default {
  setup() {
    let bg = {
      r: 0,
      //圆心坐标
      centerXy: {
        x: 0,
        y: 0,
      },
    };

    let ballDom = ref(null);
    //需要声明为响应式,不然left和top的计算属性不会生效
    let ball = reactive({
      r: 0,
      //左上角坐标
      centerXy: {
        x: 0,
        y: 0,
      },
    });
    //因为ball的left和top会根据中心坐标的改变而改变,所以要定义成计算属性
    const left = computed(() => {
      return ball.centerXy.x - ball.r;
    });
    const top = computed(() => {
      return ball.centerXy.y - ball.r;
    });
    onMounted(() => {
      //获取bg的中心坐标
      // bg.r = bgDom.value.offsetWidth / 2;
      // let xy = { x: bgDom.value.offsetLeft, y: bgDom.value.offsetTop };
      bg.r = 100;
      bg.centerXy = {
        x: 200,
        y: 200,
      };
      //最开始bg和ball都是位于container中心的
      ball.centerXy = { ...bg.centerXy };
      console.log("bg", bg);
      ball.r = ballDom.value.offsetWidth / 2;
      console.log("ball", ball);
    });

    let isMouseDown = true;
    function mouseDown() {
      isMouseDown = true;
    }
    function mouseUp() {
      isMouseDown = false;
    }
    function mouseMove(e) {
      //动画API,防止卡顿
      window.requestAnimationFrame(() => {
        if (isMouseDown) {
          //背景圆心坐标
          let x1 = bg.centerXy.x;
          let y1 = bg.centerXy.y;
          //鼠标坐标
          let x2 = e.layerX;
          let y2 = e.layerY;
          //ball与背景的圆心距
          let d = bg.r - ball.r;
          //鼠标距离背景圆心的距离
          let l = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
          console.log(
            "鼠标坐标",
            { x2, y2 },
            "圆心坐标",
            { x1, y1 },
            "鼠标距离圆心l",
            l,
            "边界d",
            d
          );
          //如果鼠标指针超出bg,ball贴边运动
          if (l >= d) {
            console.log("贴边!!");
            ball.centerXy.y = (d * (y2 - y1)) / l + y1;
            ball.centerXy.x = (d * (x2 - x1)) / l + x1;
          }
          //如果ball在bg里,ball的中心坐标就是鼠标坐标
          else if (l < d) {
            console.log("在内!!");
            ball.centerXy.x = x2;
            ball.centerXy.y = y2;
          }
        }
      });
    }

    return { ballDom, mouseDown, mouseUp, mouseMove, left, top };
  },
};
</script>
<style lang="scss" scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

$containerSize: 400px;
$bgSize: 200px;
$ballSize: 50px;

/**
outerSize是外层容器的宽
innerSize是内容元素的宽
 */
@mixin center($outerSize, $innerSize) {
  position: absolute;
  top: ($outerSize - $innerSize)/2;
  left: ($outerSize - $innerSize)/2;
}

.controllerContainer {
  background-color: #34495e;
  width: $containerSize;
  height: $containerSize;
  position: fixed;
  left: 100px;
  bottom: 100px;

  .bg {
    width: 200px;
    height: 200px;
    background-color: rgb(243, 85, 22);
    border-radius: 50%;
    transform: translate(50%, 50%);
  }

  #controllerBall {
    width: $ballSize;
    height: $ballSize;
    background-color: #2ecc71;
    border-radius: 50%;
    cursor: pointer;
    position: absolute;
    //这里定位不会生效,ball定位top与left需要设置响应式
  }
}
</style>